from flask import Flask, request, send_file
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import io
import os
from flask_cors import CORS
import subprocess

app = Flask(__name__)
CORS(app)

DATASETS_FOLDER = 'datasets'
RESULTS_FOLDER = os.path.abspath("results")  # 使用绝对路径


@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        print("No file part in the request")
        return {"error": "No file uploaded"}, 400

    file = request.files['file']

    if file.filename == '':
        print("File name is empty")
        return {"error": "No selected file"}, 400

    if file and file.filename.endswith('.csv'):
        if not os.path.exists(DATASETS_FOLDER):
            os.makedirs(DATASETS_FOLDER)

        file_path = os.path.join(DATASETS_FOLDER, file.filename)
        file.save(file_path)

        try:
            subprocess.run(["python3", "Automate_test.py"], check=True)
            print("Automate_test.py executed successfully.")
        except subprocess.CalledProcessError as e:
            print(f"Error running Automate_test.py: {e}")
            return {"error": "Analysis script failed."}, 500

        # 查找 modelAcc.csv 文件
        csv_file_path = find_model_acc_csv(RESULTS_FOLDER)
        if not csv_file_path:
            print("Error: modelAcc.csv file not found!")
            return {"error": "Analysis results not found."}, 500

        # 根据 modelAcc.csv 的路径生成 PDF 文件路径
        pdf_file_path = os.path.join(os.path.dirname(csv_file_path), "analysis_result.pdf")
        convert_csv_to_pdf(csv_file_path, pdf_file_path)

        return send_file(
            pdf_file_path,
            mimetype='application/pdf',
            as_attachment=True,
            download_name='analysis_result.pdf'
        )

    print("Invalid file format: Only CSV files are allowed")
    return {"error": "Invalid file format, only CSV is allowed"}, 400


def find_model_acc_csv(results_folder):
    """
    在 results 目录下查找最新生成的 modelAcc.csv 文件。
    """
    for root, dirs, files in os.walk(results_folder):
        for file in files:
            if file == "modelAcc.csv":
                return os.path.join(root, file)
    return None


def convert_csv_to_pdf(csv_file_path, pdf_file_path):
    if not os.path.exists(csv_file_path):
        print(f"Error: File {csv_file_path} does not exist!")
        return

    # 读取 CSV 文件
    df = pd.read_csv(csv_file_path)
    if df.empty:
        print(f"Error: File {csv_file_path} is empty!")
        return

    # 设置柱状图的输出 PDF
    with PdfPages(pdf_file_path) as pdf:
        # 创建 3x2 的子图布局
        fig, axes = plt.subplots(3, 2, figsize=(12, 15))  # 总布局大小
        axes = axes.flatten()  # 将 2D 转为 1D 索引方便迭代

        # 遍历每个列（指标）绘制柱状图
        for i, column in enumerate(df.columns[1:]):  # 跳过第一列（模型名称）
            ax = axes[i]
            ax.bar(df['Unnamed: 0'], df[column], color='skyblue')  # 绘制柱状图
            ax.set_title(f"{column} Analysis", fontsize=14)  # 设置标题
            ax.set_xlabel("Models", fontsize=10)  # 设置 x 轴标签
            ax.set_ylabel(column, fontsize=10)  # 设置 y 轴标签
            ax.tick_params(axis='x', labelrotation=45)  # 调整 x 轴标签旋转

        # 如果指标数量不足 6 个，隐藏剩余的子图
        for j in range(i + 1, len(axes)):
            fig.delaxes(axes[j])

        plt.tight_layout()  # 自动调整布局
        pdf.savefig(fig)  # 保存当前图表到 PDF
        plt.close(fig)

    print(f"PDF with bar charts generated at {pdf_file_path}")


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=3000, debug=True)